#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>

#include "types.h"
#include "solver.h"
#include "solver_OMP.h"
#include "solver_TBB.h"

typedef double* (*SolverFunc)(double* u0, Area area, double epsilon, TwoDimFunc f, int threads);

double f(double x, double y)
{
	int n = 400;
    double hx = x / n;
    double hy = y / n;
    double cx, cy;
    
    double sum = 0.0;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < n; ++j)
        {
            cx = i * hx + 0.5 * hx;
            cy = j * hy + 0.5 * hy;
            sum += sin(exp(2 * (x + y) - 2 * (x * x + y * y)) - 1) * 
                cos(exp(2 * (x + y) - 2 * (x * x + y * y)) - 1) / 
                exp(2 * (x + y) - 2 * (x * x + y * y));
        }
    }

    return sum;
}

void solving( SolverFunc solve, int setka, int threads = 1 )
{
	Area area;
    area.a = 0.0;
    area.b = 1.0;
    area.n = setka;
    int n = area.n;
    double h = (area.b - area.a) / n;
    double eps = 0.001;
    double start, finish;

    double* u0 = new double[n * n];
    
    for (int j = 0; j < area.n; ++j)
        u0[j] = 0.0;

    //srand((unsigned int)time(NULL));
    for (int i = 1; i < n - 1; ++i)
    {
        u0[i * n] = 0.0;
        for (int j = 1; j < n - 1; ++j)
        {
            u0[i * n + j] = (double)rand() / RAND_MAX;
        }
        u0[i * n + n - 1] = 0.0;
    }

    for (int j = 0; j < area.n; ++j)
        u0[(n - 1) * n + j] = 0.0;

	solve( u0, area, eps, f, threads);
	delete[] u0;
}

int main()
{
	int curr, fin, h, th;

	printf("Count of threads >> ");
	scanf("%d",&th);

	printf("\nStarting size >> ");
	scanf("%d",&curr);

	printf("\nFinishing size >> ");
	scanf("%d",&fin);

	printf("\nSize of increasing >> ");
	scanf("%d",&h);

	while( curr <= fin )
	{
		printf("\n\n====================\nCurrent size %d\n====================", curr);
		printf("\n\n STABLE \n\n");
		solving( solve ,curr);
		printf("\n\n OMP \n\n");
		solving( solve_omp ,curr, th);
		printf("\n\n TBB \n\n");
		solving( solve_tbb ,curr, th);
		curr += h;
	}

	printf("Done.\nPress any key to exit ...");
	getch();
	return 0;
}
